LScript User Guide
Previous Section Table of Contents Index Errata

LightWave 3D Modeler Commands and Functions

This section highlights each of the LScript commands that pertain specifically to LightWave 3D Modeler, as well as their calling syntaxes.

Each command in this section is marked as either CommandSequence (CS) or MeshDataEdit (MD). Due to the nature of these two different types of operations, it is illegal to execute a CommandSequence operation during a MeshDataEdit operation (initiated by editbegin() and terminated by editend()). LScript will detect any attempts to perform these illegal operations and terminate the script. Commands that are independent of this constraint are marked as Independent (IN). Included in the state designator will also be the version of LScript in which the command or feature was introduced.

PLEASE NOTE!

Describing in detail the uses of the particular Modeler- specific commands that LScript supports is quite beyond the scope of this document. These Modeler commands have already been well documented in the LightWave 3D manuals available from NewTek, Inc. What is covered is the calling syntax and return values (if any) of each command as it relates to the LScript language. For detailed descriptions of each of these Modeler commands, please consult your LightWave 3D Modeler software manual.

Unless the autoerror pragma has been declared, except where otherwise noted, all LScript Modeler-specific commands return a status value. This status value represents the result returned by the command. In general, any non-zero value indicates an error of some type.

new (CS/1.0)

The new() command will completely re-initailize the Modeler system. All layers that contain data are cleared, all internal structures and settings are reset to load-up values.

The new() command accepts an optional boolean parameter (true,false) that indicates whether the display settings (i.e., where you may have positioned windows) should be reset as well. If not specified, the default is true.

     void new(reset)               // boolean; reset screen
Be careful with this command! You can loose all unsaved work, and it cannot be undone.

undo (CS/1.0)

undo() can be called to back out a change made to your object. The number of levels of change that can be undone is specified in your LightWave Modeler configuration file (LWM.CFG).

     void undo(void)

delete (CS/1.0)

delete() will clear all point/polygon information contained in the currently-selected foreground layer(s).

     void delete(void)

cut, copy, paste (CS/1.0)

These commands allow you to manage Modeler's internal data clipboard. As with most Modeler commands, they are effective only on the currently-selected foreground layer(s).

     void cut(void)
     void copy(void)
     void paste(void)

load, save (CS/1.0)

load() and save() allow you to access LightWave objects on disk. These commands effect data in the currently-selected foreground layer(s).

     status load(string)
     status save(string)

lyrfg, lyrbg, lyrdata, lyrempty, lyremptyfg,
lyremptybg, lyrswap, lyrsetfg, lyrsetbg

These functions constitute the sum total of LScripts layer handling functions. These functions allow script programmers to dynamically manage layer settings in Modeler.

lyrfg, lyrbg (IN/1.2)

These commands return the Modeler layers that are currently selected into the foreground--if the lyrfg() command is used--or the background--if the lyrbg() command is invoked. Layer numbers are returned in the range 1 to 10. Typically, you will want to assign the return value of each of these commands to an array, but you can assign to a non-array variable by using associative assignments.

Usually, you will use these commands to "remember" the layers that the user has actively selected before your LScript starts changing any settings. When you are done, you should politely restore the users original layer settings by passing these values to the lyrsetfg() (or lyrsetbg() if the array contains active background information).

The prototypes for these functions are as follows:

     result                        // integer[]; one or
                                        // more layer values
       lyrfg(void)
     result                        // integer[]; one or
                                        // more layer values
       lyrbg(void)

lyrdata, lyrempty (IN/1.2)

Each of these function returns an array of elements representing the layer numbers that either contain mesh data (lyrdata), or are empty of all data (lyrempty).

These functions will return a layer value, regardless of whether the layer is active foreground, active background, or entirely unselected. The prototypes for these functions are as follows:

     result                        // integer[]; one or
                                        // more layer values
       lyrdata(void)
     result                        // integer[]; one or
                                        // more layer values
       lyrempty(void)

lyremptyfg, lyremptybg (IN/1.2)

lyremptyfg() and lyremptybg() will return empty layers in the currently-selected foreground or background layer(s), respectively.

     result                        // integer[]; one or
                                        // more layer values
       lyremptyfg(void)

     result                        // integer[]; one or
                                        // more layer values
       lyremptybg(void)

lyrswap (CS/1.2)

lyrswap() can be used to instantly reverse the currently selected layer(s). Selected foreground layer(s) become selected background layer(s), while selected background layer(s) become the active foreground layers(s).

This command is identical to the single-quote key (') used in Modeler to swap layers.

     void lyrswap(void)

lyrsetfg, lyrsetbg (IN/1.2)

Each of these function accepts either an array of integer numbers, or a variable number of integer values, indicating the layer(s) to be selected as active. In the current implementation of LightWave Modeler, layers are numbered from 1 to 10.

The prototypes for these functions are as follows:

     void lyrsetfg(lyr1           // integer; layer number
                   [,lyr2...lyr10])    // additional layers

     void lyrsetbg(layers)        // integer[]; elements are
                                       // layers numbers

fixedflex (CS/1.0)

This function allows the script programmer to establish operating parameters for other Modeler commands that involve flex transformations. These flexing commands include twist() and taper().

fixedflex() sets the operating parameters for these flex functions so that they operate on a fixed range along a specified axis. Easements can be specified using the "i" (ease-in) or "o" (ease-out) flags.

     status fixedflex(axis,        // constant; X, Y or Z
                      start,       // number; start of range
                                        // in degrees
                      end          // number; end of range
                                        // in degrees
                      easement)    // string; "i" or "o"

autoflex (CS/1.0)

Like fixedflex(), this function modifies the operational parameters for flex transformation functions. However, this function sets parameters so these flexing commands will operate on an automatic range along the axis of the specified polarity.

     status autoflex(axis,         // constant; X, Y or Z
                     polarity,     // string; "+" or "-"
                     easement)     // string; "i" or "o"

deformregion (CS/1.0)

This command establishes the area of 3D space that deformation functions, such as vortext() and pole(), will use during their operation. If the optional axis is omitted, the deformation effect is bounded in all directions by the specified radius. If an axis is indicated, the effect is unbounded along that particular axis.

     status deformregion(radius    // vector or number; radius
                                        // of region
                         [,center  // vector or number; center
                                        // of region
                         [,axis]]) // constant; X, Y or Z

move (CS/1.0)

move() translates selected points by a specified offset. Note that the offset is relative to the center of the selected points, and not from the origin.

     void move(offset)             // vector or number;
                                        // movement offset
                                        // along all three
                                        // axes

     void move(xoffset,            // number; offset along X
                                        // axis
               yoffset,            // number; offset along Y
                                        // axis
               zoffset);           // number; offset along Z
                                        // axis

shear (CS/1.0)

Similar to move(), shear() translates selected points by a specified offset. However, points are only translated along the flex axis (established by the fixedflex() or autoflex() commands). Note that the offset is relative to the center of the selected points, and not from the origin.

     void shear(offset)            // vector or number; offset
                                        // value to apply to
                                        // all axes

     void shear(xoffset,           // number; offset along X
                                        // axis
                yoffset,           // number; offset along Y
                                        // axis
                zoffset);          // number; offset along Z
                                        // axis

magnet (CS/1.0)

magnet() also translates selected points by a specified offset, but the translation falls within the area established by the deformation region (established by the deformregion() command).

     void magnet(offset)           // vector or number; offset
                                        // value to apply to
                                        // all axes

     void magnet(xoffset,          // number; offset along X
                                        // axis
                 yoffset,          // number; offset along Y
                                        // axis
                 zoffset);         // number; offset along Z
                                        // axis

rotate (CS/1.0)

rotate() is used to rotate selected points along a specified axis by a specified number of degrees.

     status rotate(angle,          // number; amount of
                                        // degrees to rotate
                   axis            // constant; X, Y or Z
                   [,center])      // vector or number; center
                                        // of rotation

twist (CS/1.0)

Like rotate(), twist() will rotate selected points along a specified axis by a specified number of degrees. However, points are only translated along the flex axis (specified by the fixedflex() or autoflex() commands).

     status twist(angle,           // number; amount of
                                        // degrees to twist
                  axis             // constant; X, Y or Z
                  [,center])       // vector or number; center
                                        // of twist

vortex (CS/1.0)

vortex() is also used to rotate selected points along a specified axis by a specified number of degrees. However, this command operates within the deformation region, whose parameters are established using the deformregion() command.

     status vortex(angle,          // number; amount of vortex
                                        // degrees
                   axis            // constant; X, Y or Z
                   [,center])      // vector or number; center
                                        // of vortex

scale (CS/1.0)

scale() is used to scale selected points by a given factor around an optional center point. Factors of 1 on any axis will maintain the points in their locations along that axis.

For example, to scale an object by one-half along the X and Y axes, while maintaining the current scale along the Z,

     scale(<.5,.5,1>);
Notice in the example that no optional center vector was specified. This value will default to the origin (i.e., <0,0,0>), and all values will be relative to this point.

     status scale(amount           // vector or number;
                                        // scaling factor
                  [,center])       // vector or number;
                                        // relative center of
                                        // scale

taper (CS/1.0)

taper() is similar to scale() except that it uses the flex axis, established by either fixedflex() or autoflex(), to define its area of influence.

     status taper(amount           // vector or number;
                                        // tapering factor
                  [,center])       // vector or number;
                                        // relative center of
                                        // taper

pole (CS/1.0)

pole(), like taper(), is another member of the scale() family, except that it uses the deformation region, established by deformregion(), to constrain its area of influence.

     status pole(amount            // vector or number; pole
                                        // factor
                 [,center])        // vector or number;
                                        // relative center of
                                        // pole

bend (CS/1.0)

This command is used to bend selected points by a specified angle in a direction around an optional center. bend() adheres to the current flex axis established by either fixedflex() or autoflex().

     status bend(angle,            // number; bend angle in
                                        // degrees
                 direction         // number; bend direction
                                        // in degrees
                 [,center])        // vector or number;
                                        // relative center
                                        // around which to
                                        // bend

jitter (CS/1.0)

jitter() will randomly translate selected points using one of four different displacement functions.


        UNIFORM
        
distributes points across a uniform range. This is the default

        GAUSSIAN
        
distributes the offsets in a bell curve around the starting point

        NORMAL
        
shifts the points in and out along the local surface normal

        RADIAL
        
shifts points in and out along a line through a central point given by the center parameter

The prototype for jitter() is

     status jitter(radius          // number; jitter radius
                   [,type          // constant; UNIFORM,
                                        // GAUSSIAN, NORMAL,
                                        // or RADIAL
                   [,cntr]])       // vector or number;
                                        // central point used
                                        // by RADIAL

smooth (CS/1.0)

smooth() is used to remove "kinks" in polygons that are connecting affected points.

     status smooth([iterations     // number; number of passes
                                        // to use
                   [,strength]])   // number; strength of
                                        // smoothing

quantize (CS/1.0)

You can use this command to snap all the selected points to a three-dimensional grid defined by the size parameter.

     status quantize(size)         // vector or number;
                                        // defines 3D grid

mergepoints (CS/1.0)

mergepoints() can be used to merge selected points lying within a certain minimum distance of each other. If the optional distance value is omitted, it is computed automatically.

     status mergepoints([dist])    // number; the minimum
                                        // point distance

makebox (CS/1.0)

This command will create a three-dimensional box object with the specified extents and divisions.

     status makebox(lowcorner,     // vector or number; low
                                        // boundary point
                    highcorner     // vector or number;
                                        // high boundary point
                    [,nsegments])  // vector or number; count
                                        // of box segments

makeball (CS/1.0)

This command will create a three-dimensional, globe-like sphere.

     status makeball(radius        // vector or number; radius
                                        // of sphere
                     nsides        // integer; number of
                                        // sphere sides
                     nsegments     // integer; number of
                                        // sphere segments
                     [,center])    // vector or number; center
                                        // of sphere

maketesball (CS/1.0)

maketesball() is used to create a tessellated sphere. A tessellated sphere is similar to a globe sphere whose four-sided polygons have been tripled. The level parameter determines the amount of tessellation to be applied.

     status maketesball(radius     // vector or number; radius
                                        // of sphere
                        level      // integer; level of
                                        // tessellation
                        [,center]) // vector or number; center
                                        // of sphere

makedisc, makecone (CS/1.0)

Use the makedisc() command to create a cylindrical object with the number of sides and segments specified. The higher the number of sides, the smoother the cylinder will be.

makecone() accepts that same parameters as makedisc(). However, makecone() will cause the top of the cylinder to narrow to a single point.

     status makedisc(radius,       // vector or number; radius
                                        // of disc
                     top,          // number; cylinder top
                                        // along axis
                     bottom,       // number; cylinder bottom
                                        // along axis
                     axis,         // constant; X, Y or Z
                     nsides        // integer; number of side
                     [,nsegments   // integer; number of
                                        // segments (1)
                     [,center]])   // vector or number; center
                                        // of object

maketext (CS/1.0)

This function will create a Modeler object comprised of the characters in a string. The resulting object will take on the aspect of the character font that has been loaded with the fontload() function. The font index value returned by fontload() must be passed to the maketext() function.

The following LScript code snippet illustrates the use of these functions (taken from the logo.ls example script):

     findex = fontload(fontName);

     if(findex != nil)
     {
         maketext("LScript",findex);
maketext() returns the width (in meters) of the resulting Modeler object.

     number  maketext(text,        // string; text to convert
                      index,       // integer; font index from
                                        // fontload()
                      [,cornertype // constant; SHARP or
                                        // BUFFERED
                      [,spacing    // number; spacing between
                                        // characters
                      [,scale      // number; character
                                        // scaling factor
                      [,axis       // constant; X, Y or Z
                      [,pos]]]])   // vector or number;
                                        // position of first
                                        // character

lathe (CS/1.0)

lathe() will spin the current object around the specified axis, creating a new object with the indicated number of sides. The object to be lathed will typically be a two- dimensional template.

     status lathe(axis             // constant; X, Y or Z
                  nsides           // integer; number of sides
                                        // for new object
                  [,center         // vector or number; center
                                        // about which to
                                        // lathe
                  [, end           // number; ending angle in
                                        // degrees
                  [, start]]])     // number; starting
                                        // angle in degrees

extrude (CS/1.0)

extrude() is used to extend an object along a specified axis, optionally adding segments.

     status extrude(axis,          // constant; X, Y or Z
                    extent         // number; distance to
                                        // extend along axis
                    [,nsegments])  // integer; number of
                                        // additional segments
                                        // (default is 1)

mirror (CS/1.0)

This command will copy selected data through a plane, rotating it 180 degrees.

     status mirror(axis,           // constant; X, Y or Z
                   offset)         // number; offset of plane
                                        // along axis

pathclone, pathextrude (CS/1.0)

These two commands allow you to duplicate (clone) or extrude an object along a motion path created in and saved from LightWave 3D Layout. The optional start, end, and step parameters can be thought of as arguments to a loop counter. When you omit them, the starting and ending frames embedded in the motion path file are used as start and end, with a default step value of 1. By specifying these values, you can override those that appear in the motion path file.

You can vary the start and end values to cause your object to clone or extrude only along the portion of the motion path represented by those values. For instance, if a motion path were loaded that required 330 frames to traverse, issuing the command

     pathextrude("my.mot",1,200,300);
would cause your object to begin its extrusion at the frame-200 position of the motion path and continue on through frame-300 position. The sections of the path where your object would have extruded from frames 1 to 199, and from frames 301 to 330, will be empty.

Cloning an object using pathclone() will create a unique duplicate of your object at each step interval. Electing to extrude your object using pathextrude() will create one single, new object with a new segment at each step interval.

Both commands accept the same parameter counts and types.

     status pathextrude(filename,  // string; name of motion
                                        // path file
                        [,step     // number; count of
                                        // objects/segments to
                                        // create
                        [,start    // number; starting count
                        [,end]]])  // number; ending count

railclone, railextrude (CS/1.0)

railclone() and railextrude() are very similar to pathclone() and pathextrude() in that they will duplicate or extrude an object. Unlike their cousins, the rail commands operate using Modeler curves instead of motion path files. The curve (rail) to be used for either command must reside in a currently-active background layer.

     status railextrude(segments   // number; segment count
                                        // (0=compute)
                        [,div      // constant; KNOTS or
                                        // LENGTHS
                        [,flags    // string; "o" (orient) or
                                        // "s" (scaled)
                        [,strength]]])  // number

axisdrill (CS/1.0)

axisdrill() uses the two-dimensional object in the active background layer(s) as a template to "drill" through the object in the active foreground layer(s). Four different drilling operations are provided with axisdrill():


        CORE
        
drill out the foreground polygons that fall within the background template's shape, leaving only the core

        TUNNEL
        
opposite of CORE; removes polygons that fall within the template's shape, leaving non-core data

        SLICE
        
cut's through the foreground object, creating a visible incision along the template's edges

        STENCIL
        
identical to SLICE, except you can assign a surface name to all polygons that fall within the template's shape

The optional surface parameter is used when the STENCIL operation is specified.

     status axisdrill(operation,   // constant, CORE, TUNNEL,
                                        // SLICE or STENCIL
                      axis         // constant, X, Y or Z
                      [,surface])  // string, surface name
                                        // (for STENCIL)

soliddrill (CS/1.0)

soliddrill() is largely identical to axisdrill(), except that a) it uses a three-dimensional object in the active background layer(s), and b) it requires that the volume of the two objects (foreground and background) overlap.

     status soliddrill(operation   // constant, CORE, TUNNEL,
                                        // SLICE or STENCIL
                       [,surface]) // string, surface name
                                        // (for STENCIL)

boolean (CS/1.0)

This command causes the object in the active foreground layer(s) to be combined with the object in the active background layer(s). Four types of boolean operation are support:


        UNION
        
merge the volumes of each object into a single, new object; interior surfaces where the two object overlap will be removed

        SUBTRACT
        
remove the volume of the background object(s) from the foreground object(s)

        INTERSECT
        
create an object that is the area the two objects had in common

        ADD
        
add background object(s) to the foreground object(s); intersection of polygons are sliced to form a common edge

     status boolean(operation)     // constant, UNION,
                                        // SUBTRACT, INTERSECT
                                        // or ADD

bevel (CS/1.0)

The bevel() command allows you to add beveled edges to an object by specifying both inset and shift amounts.

     status bevel(inset,           // number; uniform amount
                                        // of displacement
                                        // along polygon plane
                  shift)           // number; displacement
                                        // amount
                                        // perpendicular to
                                        // polygon plane

shapebevel (CS/1.0)

shapebevel() also adds a beveled edge to an object. However, it accepts a series of inset/shift pairs contained in a character string. Within the string, the inset/shift pairs are separated by a space. The same effect can be achieved using iterative or sequential bevel()'s, but the results are not always correct because of the self-crossing effect that can occur.

The example script router.ls relies heavily on this command for its functionality. The following code snippet that illustrates the usage of this command was taken from that script:

     s = string(-wide," ",wide," ",-wide," ",deep / 2);
     shapebevel(s);
The prototype for this command appears as

     status shapebevel(pattern)    // string; pairs of
                                        // inset/shift pairs

smoothshift (CS/1.0)

This command will shift selected polygons by a specified offset. Any angles greater than maxangle will cause the surface to break.

     status smoothshift(offset     // number; shift offset
                        [,max])    // number; maximum angle in
                                        // degrees

flip (CS/1.0)

flip() is used to reverse the surface normal of selected polygons. It can also be used to reverse the direction of Modeler curves.

     status flip(void)

triple (CS/1.0)

triple() is used to convert all selected polygons into triangles.

     status triple(void)
In particular, you will want to triple() an object (especially if it contains 4-sided polygons) prior to subdividing it. The following code snippet illustrates this:

     points = polycount();

     if(points[5] or points[6])
          // it has polygons with 4 or more sides
          triple()

     subdivide(METAFORM);

freezecurves (CS/1.0)

Use freezecurves() to convert all selected Modeler curves directly into polygons.

     status freezecurves(void)

alignpols (CS/1.0)

This command "flips" all selected polygons so they are facing the same direction (as much as is possible).

     status alignpols(void)

removepols (CS/1.0)

removepols() will delete all selected polygons, leaving only their points.

     status removepols(void)

unifypols (CS/1.0)

unifypols() will remove any duplicate polygons.

     status unifypols(void)

subdivide (CS/1.0)

You can use subdivide() to split all triangles into four smaller triangles. This command will also split quads into four smaller quads. subdivide() supports three different forms:


        FLAT
        
subdivide polygons, leaving the newly divided polygons in the same plane as the originals

        SMOOTH
        
extrapolates where subdivided detail should be placed to maintain and enhance the curvature of the original form

        METAFORM
        
smooths dramatically; locations which contain greater detail will have more detail in the smoothing process

     status subdivide(mode         // constant; FLAT, SMOOTH
                                        // or METAFORM
                      [,max])      // number; maximum angle to
                                        // consider (in
                                        // degrees)

fracsubdivide (CS/1.0)

fracsubdivide() is similar to subdivide(), except that it allows you to apply a fractal displacement value to each new vertex as a function of its position.

     status fracsubdivide(mode,    // constant; FLAT, SMOOTH
                                        // or METAFORM
                          fractal  // number; fractal
                                        // displacement amount
                          [,max])  // number; maximum angle to
                                        // consider (in
                                        // degrees)

selpoint (CS/1.0)

Out of all other LScript commands (except possibly selpolygon(), discussed next), selpoint() has the most complex parameter structure. selpoint() contains two "major modes" and a plethora of "minor modes" who each have their own parameter counts and types. The major modes for selpoint() are:

SET the minor mode that follows, if any, will define points that are to be selected CLEAR the minor mode that follows, if any, will define points that are to be deselected One of these two major modes will always be the first parameter to selpoint(). They are the only non-optional parameters to the command, and can appear in the parameter list by themselves (i.e., selpoint(CLEAR) will deselect all currently-selected points).

The minor modes supported by selpoint() allow the script programmer to designate point selection in a number of different ways. The minor modes for selpoint() include:

Minor Mode Arguments Description

        VOLUME
        
two vectors, indicating the low and high points of the bounding box selects/clears points that fall within a specified bounding box.

        CONNECT
        
none selects points that are connected to points that are already selected. Only works with the SET major mode.

        NPEQ
        
number, indicating the count of points that qualifying polygons should contain selects/clears all points belonging to polygons that contain exactly the number of points specified by the argument.

        NPLT
        
number, indicating the count of points that qualifying polygons should not exceed selects/clears all points belonging to polygons that contain fewer than the number of points specified by the argument.

        NPGT
        
number, indicating the count of points that qualifying polygons should exceed selects/clears all points belonging to polygons that contain more than the number of points specified by the argument.

        POINTNDX
        
number, representing the linear index of the point; array, containing a list of integer values that represent linear point indices; initialization block, containing integer values representing linear point indices. selects/clears the point that exists in Modeler's internal list of points at the specified index

        POINTID
        
point identifier, derived from some MeshDataEdit mode function; or an array or initialization block of point identifiers, as described in POINTNDX. selects/clears all points identified by the provided point identifier(s)

It is important to note that you need to set your script into USER mode using the selmode() command before selpoint() (and selpolygon()) will work properly.

Here, then, is the prototype for selpoint():

     status selpoint(major         // constant; SET or CLEAR
                     [,minor,      // constant; VOLUME,
                                        // CONNECT, NPEQ,
                                        // NPLT, NPGT or
                                        // POINTID
                     params])      // varies; minor-mode
                                        // parameters
                                        // outlined previously

selpolygon (CS/1.0)

selpolygon() is a companion command to selpoint() that allows the script programmer to select/deselect whole polygons instead of single points. While its major modes are identical to selpoint(), its minor modes vary in both numbers and functionality:

Minor Mode Arguments Description

        VOLEXCL
        
two vectors, indicating the low and high points of the bounding box selects/clears polygons whose points fall completely within the specified bounding box

        VOLINCL
        
two vectors, indicating the low and high points of the bounding box selects/clears polygons that have at least one point that falls within the specified bounding box

        CONNECT
        
none selects polygons that are connected to polygons that are already selected. Only works with the SET major mode.

        NVEQ
        
number, indicating the count of vertices that qualifying polygons should contain selects/clears all polygons that contain exactly the number of vertices specified by the argument.

        NVLT
        
number, indicating the count of vertices that qualifying polygons should not exceed selects/clears all polygons that contain fewer than the number of vertices specified by the argument.

        NVGT
        
number, indicating the count of vertcies that qualifying polygons should exceed selects/clears all polygons that contain more than the number of vertices specified by the argument.

        SURFACE
        
string, indicating the name of the surface assigned to qualified polygons selects/clears all polygons that have been assigned the specified surface name.

        FACE
        
none selects/clears all polygons that Modeler considers to be of type "face".

        CURVE
        
none selects/clears all polygons that Modeler considers to be of type "curve".

        NONPLANAR
        
number, an optional numeric value that indicates the planar selection limit selects/clears polygons who are less planar than the specified argument. if the optional argument is omitted, then the user's default planar limit will be used.

        POLYNDX
        
number, representing the linear index of the polygon; array, containing a list of integer values that represent linear polygon indices; initialization block, containing integer values representing linear polygon indices. selects/clears the polygon that exists in Modeler's internal list of polygons at the specified index

        POLYID
        
polygon identifier, derived from some MeshDataEdit mode function; or an array or initialization block of polygon identifiers, as described in POLYNDX. selects/clears all polygons identified by the provided polygon identifier(s)

As with selpoint(), you must set your script session into USER mode using the selmode() command for selpolygon() to function properly.

     status selpolygon(major       // constant; SET or CLEAR
                       [,minor,    // constant; VOLEXCL,
                                        // VOLINCL, CONNECT,
                                        // NVEQ, NVLT, NVGT,
                                        // SURFACE, FACE,
                                        // CURVE, NONPLANAR
                                        // or POLYID
                       params])    // varies; minor-mode
                                        // parameters
                                        // outlined previously

selinvert (CS/1.0)

This command will invert the current selection state (i.e., selected items become deselected while unselected items become selected).

     status selinvert(void)

selhide (CS/1.0)

selhide() will hide from view all data that is either selected, if the SELECTED option is used, or unselected, if the UNSELECTED option is elected.

     status selhide(which)         // constant; SELECTED or
                                        // UNSELECTED

selunhide (CS/1.0)

This command is a companion to selhide(), and is used to bring the hidden data back into view.

     status selunhide(void)

setsurface (CS/1.0)

setsurface() sets the surface name to which all new data will be assigned. If it does not exist, it will be created.

     status setsurface(name)       // string; new surface name

getdefaultsurface (IN/1.0)

This command returns the currently-selected surface name.

     string getdefaultsurface(void)

changesurface (CS/1.0)

changesurface() will assign all currently-selected polygons to a new or existing surface name.

     status changesurface(name)    // string; surface name to
                                        // which selected
                                        // polygons will
                                        // belong

nextsurface (IN/1.0)

nextsurface() allows you to navigate through Modeler's internal list of surface names. Calling nextsurface() without parameters will return the first surface name in Modeler's list. The next surface name can be returned by passing nextsurface() the name of the surface that precedes it. If the surface name provided occupies the end of the list, a value of nil will be returned.

     // display all the current surface names

     var surface = nextsurface();

     info(surface);

     while(true)
     {
         if((surface = nextsurface(surface)) == nil)
             break;

         info(surface);
     }
The prototype:

     result                        // string; surface name
       nextsurface([name])         // string; optional surface
                                        // name

renamesurface (IN/1.0)

renamesurface() allows the script programmer to change the name of an existing surface. Once renamed, the original surface name will no longer exist.

     status renamesurface(orig,    // string; existing surface
                                        // name
                          new)     // string; new surface name

createsurface (IN/1.0)

This command will add a new surface name to Modeler's internal list. If a surface with this name already exist, no action is taken.

     status createsurface(name)    // string; new surface name

copysurface (IN/1.2)

This command will add a new surface name to Modeler's internal list, and copy the attributes of an existing surface into it.

     status copysurface(orig,    // string; existing surface name
                        new)     // string; new surface name

fontcount (IN/1.0)

fontcount() will return the number of fonts that are currently loaded into Modeler. If the internal font list is empty, nil is returned.

     result                        // integer; number of fonts
                                        // loaded
       fontcount(void)

fontindex (IN/1.0)

Given a font name, fontindex() will return the index value of that font. If the specified font cannot be located, nil is returned.

     result                        // integer; font index
       fontindex(name)             // string; font name

fontname (IN/1.0)

Given a font index (returned by either fontload() or fontindex()), fontname() will return the name of the specified font. If the provided index is invalid, nil is returned.

     result                        // string or nil; font name
       fontname(index)             // integer; font index
                                        // value

fontload (IN/1.0)

fontload() gives script programmers the capability to load Postscript fonts into Modeler for use with the text creation commands. The companion command fontclear() (discussed next) should be called when you are finished with a particular font.

     var fontName = getfile("Select a Font");

     if(fontName == nil)
         return;

     var findex = fontload(fontName);

     if(findex != nil)
     {
         maketext("LScript",findex);
         fontclear(findex);  // release the font immediately
     ...
The prototype:

     result                        // integer; font index
                                        // or nil
       fontload(name)              // string; font name with
                                        // optional path

fontclear (IN/1.0)

fontclear() should be called when you no longer need a Modeler font that has been loaded with the fontload() command.

     status fontclear(index)       // integer; font index
                                        // value

cmdseq (CS/1.0)

cmdseq() allows your LScript to invoke other plugins that have been installed into Modeler. This interface to other plugins is unidirectional, meaning you can pass information to them, but they cannot return values.

The name used to invoke another plugin should be identical to the name as that appears under your Custom menu button. The arguments you pass to a plugin depend upon how that plugin has been programmed. Most plugins will not accept parameters, not having been specifically designed to be invoked in this fashion.

     status cmdseq(name            // string; plugin name
                   [,arguments])   // string; value varies by
                                        // plugin

getfile (CS/1.0)

getfile() provides your LScript an interface to file selection. When you need to allow the user to specify a disk file, getfile() will post a file-selection dialog box, and return the file name (including path information) that the user has selected. If the user decides to cancel, getfile() will return nil.

All of getfile()'s parameters are optional. You can specify a title for the dialog box, a file name mask to be used, and even a default directory to use.

     result                        // string or nil; file name
       getfile([title              // string; dialog box title
               [,mask              // string; file mask to use
                                        // (can include
                                        // wildcards)
               [,dir]]])           // string; directory path
                                        // in which to begin

moninit (IN/1.0)

This command is the entry point to the monitor control commands. moninit() will initialize a monitor window for your script. This command must be called before other monitor commands can be used.

The monitor system is basically a progress indicator. A progress indicator let's your user know that things are actually taking place, and that the computer has not locked-up for some reason. You initialize the monitor by telling it how many steps you need to take before you have completed your work. The monitor system uses this value to display a graphical progress bar so that the user knows how much more time will be required until completion.

You can optionally provide a message that will be displayed to the user in the monitor dialog box during display. Notice that the monitor window is actually a dialog. The user can press a Cancel button provided by the dialog box at anytime. This action is handled by the monstep() function (discussed next).

     void moninit(steps            // integer; number of steps
                                        // until completion
                  [,message])      // string; message to be
                                        // displayed to user

monstep (IN/1.0)

monstep() is used to advance the progress indicated (created with moninit()) by a specific distance. If no value is provided, the advance count defaults to 1. You can advance the progress indicator by larger values simply by specifying them.

monstep() will return a Boolean value. Most of the time, this value will be false. However, should the user press the Cancel button on the monitor window, this command will return true. When this takes place, your script should exit as gracefully as possible.

     editbegin();
     ...
         if(monstep())
         {
             lyrsetfg(fg);
             lyrsetbg(bg);
             editend(ABORT);
             return;
         }
And the prototype:

     boolean monstep([step])       // integer; optional
                                        // advance amount

monend (IN/1.0)

This command completes the monitor system, closing the progress window if one is open, and frees up the monitor system for other parts of Modeler (only one monitor window can be activate at a time).

     void monend(void)

reqbegin (CS/1.0)

Modeler provides an interface mechanism that allows plugins to interact with their users. LScript taps this mechanism to provide the same facilities to script programmers. reqbegin() is the entry point into these interface functions.

reqbegin() is called to initiate a Modeler "requester." This requester is basically an input dialog box used to gather information and options from the user. It can also be used to impart information and messages (as static text).

Invoking reqbegin() will place you into requester mode. This mode must be active for other requester-related functions to be used , and must be terminated by a call to reqend(). You may terminate your script at any time during requester mode, and LScript will automatically issue a reqend() if you forget to do so.

reqbegin() takes a single argument, which is the title to be used for your requester dialog.

     void reqbegin(title)          // string; dialog box title

reqend (CS/1.0)

reqend() is the terminator to requester mode. It should be used to terminate a requester dialog after all processing of user input is complete.

     void reqend(void)

reqpost (CS/1.0)

This command informs the requester system that you have finished construction of your requester dialog, having populated it with your required fields, and that you wish to have the dialog displayed for user interaction.

reqpost() will return a Boolean value (true or false) indicating whether or not the user chose to continue processing with the provided values. A value of true indicates that the user selected Ok, and that processing should commence. A false return is an indicator that your should gracefully terminate your script because the user has decided to Cancel.

     result                        // boolean; true if user
                                        // selected "Ok"
       reqpost(void)

ctlstring, ctlinteger, ctlnumber, ctlvector, ctldistance, ctlchoice,
ctltext, ctlcolor, ctlsurface, ctlfont (CS/1.2)

These functions constitute the bulk of Modeler LScript's control creation suite. Each function accepts a control title as its first parameter, and returns a control identifier (to be used later by the getvalue() function). Each control is provided its initial value by the second (and, in some cases, subsequent) parameter.

ctlstring, ctlinteger, ctlnumber, ctlvector

These functions provide for the creation of edit controls for simply data types, namely character strings, integers, floating point numeric values, and vectors (tuples of floating point numbers).

     ...
     name = "BillyBob";
     age = 18;

     c1 = ctlstring("Your name?",name);
     c2 = ctlinteger("Your age?",age);
     ...
ctlvector() accepts a rather flexible format in its parameters. You can provide a single vector data type, a single numeric value that will be used to populate all three fields, or you can provide three individual numeric values to be used to initialize the individual edit fields.

ctldistance

The ctldistance() function is used exactly as you would use ctlnumber(), however the resulting edit control will display and edit values based upon Modelers current default units of measurement.

     ...
     length = .25;

     c1 = ctldistance("Length",length);  // if selected default units are
                                         // kilometers, then this edit
                                         // field will initially be
                                         // (.25 * 1k) == 250 meters
     ...

ctlchoice

Controls can also be enumerated selection lists. These lists are displayed by the Modeler requester system as push buttons grouped in the same location. You create a push-button selection control using ctlchoice().

ctlchoice() requires three parameters, and accepts an optional fourth. The first, as with all other control-creation functions, is the control title. The second is an integer value, used to specify the initial push button that will be selected when the panel is posted. The third is either an array reference containing the character strings that will be used as the button labels, or it can be an initialization block placed directly into the function call that houses the same data. Selection numbers begin at one (1).

     booleans[1] = "Yes";
     booleans[2] = "No";
     choice = 2;        // set "No" as initial selection

     c1 = ctlchoice("Use random height?",choice,booleans);
The (optional) fourth parameter can be provided to indicate the orientation of the selection list. Selection lists can be organized with either vertical or horizontal grouping. This fourth parameter selects a specific orientation by specifying a Boolean true for vertical and false for horizontal. If omitted, horizontal orientation is used by default.

     choice = 1;        // set "No" as initial selection

     // create a vertical selection list
     c1 = ctlchoice("Quadrant?",choice,@"90","180","270"@,true);

ctltext

ctltext() is used to add static text to the requester dialog box. This static text could be used to impart messages to the user concerning special instructions or circumstances surrounding input values.

ctltext() accepts a variable number of arguments, all of which should be text strings. As with all control-creation functions, the first text string provided is always treated as the control title.

     ctltext("WARNING",  // <-- first arg is control title
             "This operation could take a long time,",
             "and create very many points if Level is high");
Like all other control functions, ctltext() will return the control handle of the static text control. However, because the control does not change, this handle is of little value. It could be used by the setvalue() function to alter the text before re-posting the dialog box.

ctlcolor

The control behaves similarly to ctlvector() in that it posts a control that has three separate numeric editing fields. However, where ctlvector() allows the script user to edit floating point values, ctlcolor() only allows integer values to be entered into its fields.

As with ctlvector(), ctlcolor() also accepts a combination of parameters and types. You can provide a single vector data type, a single integer value that will be used to populate all three fields, or you can provide three individual integer values to be used to initialize the individual edit fields.

ctlsurface, ctlfont

These two functions create controls that allow you to manage Modelers surface and font attributes, respectively. The controls created often will have a number of other controls themselves, related to the particular features of the control type.

Both functions take the control title from the first parameter provided. ctlsurface() assumes that the second string parameter is the name of a surface to be used to initialize the surface control. cltfont() requires an integer value as its second parameter that indicates the index of a currently-loaded font that is to be used as the control's initial value.

getvalue (CS/1.0)

getvalue() is used to retrieve the value in an input field. The control handle returned by one of the control creation functions must be provided to this function. The type of the return value will depend upon the type of the control. It is customary to assign the return value of getvalue() to the original variable used to initialize the input control.

     result                        // varies; data value
                                        // contained in field
       getvalue(handle)            // integer; control handle

setvalue (CS/1.0)

Until reqend() is called, a constructed requester dialog can be posted to the user for input as many times as is required. Although the controls themselves cannot be modified--that would require destroying the current requestor with reqend(), creating a new one with reqbegin(), and populating it with new controls--the values they contain can be changed before re-posting.

setvalue() allows you to modify the value of an existing requester control. It accepts a handle to the control to be changed, and a variable or constant value to used as the new value. Please examine the lightswa.ls script, provided on your LightWave distribution, for an example of this practice.

     void setvalue(handle,         // integer; control handle
                   value)          // data type; new value for
                                        // input field

listadd, listremove (CS/1.0)

These two commands enable LScripts to add and remove items to Modeler's User menu under the Objects panel. Typically, you would use these commands to add LScripts directly to the User menu. Adding scripts in this fashion enables LScripts to be executed directly, without the need to invoke LScript and navigate through the file-selection dialog box.

Using listadd(), you can establish the name that will appear under the User menu, the server to be used to process the selection (in the case of LScripts, the server name would be "LScript"), and the file name (with optional path) of the file that represents the entry.

listremove() can be used to remove an entry from the User menu. Only the name of the User menu entry needs to be provided.

When server-based entries are placed in the User menu in this fashion, Modeler maintains them separately from its own internal commands (i.e., Add Plugin) and plugins. To accomplish this, your server-based entries are stored in a specific file that it will automatically reload each time you start Modeler. However, for Modeler to be aware of these commands, you must save them during the session in which you╞ve added them. To save your new entries for later loading, use the Configure List command under the User menu. See your Modeler documentation for more information.

     status listadd(title,         // string; title of entry
                                        // under User menu
                    server,        // string; name of server
                                        // to be used to
                                        // process entry
                    file)          // string; disk file to
                                        // which this entry
                                        // points

     status listremove(title)      // string; title of entry
                                        // to be removed

selmode (IN/1.0)

The selection mode is used by a number of different Modeler-specific commands, particularly the selpoint() and selpolygon() commands. Selection mode can be either GLOBAL or USER. GLOBAL selection is the default mode.

In GLOBAL selection mode, Modeler-specific operations will occur on all points/polygons in the active foreground layer(s), regardless of what user-selected data exists. USER selection mode will cause Modeler-specific commands to operate only on those points and polygons that have been explicitly selected by the user (or implicitly on all points and polygons if no user-selected data exists).

The selection commands selpoint() and selpolygon() will not function unless the USER selection mode is active.

     void selmode(mode)            // constant; GLOBAL or USER

editbegin (MD/1.0)

editbegin() is the entry point into the MeshDataEdit functions that LScript supports. While CommandSequence (CS/1.0) commands offer the ability to operate on points and polygons collectively, MeshDataEdit (MD/1.0) operations offer script programmers the capability to edit individual point and polygon data directly.

editbegin() places your LScript into MeshDataEdit mode. When you enter this mode, certain magical things take place:

1. CommandSequence (CS/1.0) commands and functions are
now illegal. You may not invoke these types of
procedures until you leave MeshDataEdit mode
using editend().
2. Two new, automatic LScript arrays become available.
The first, called points[], contain the point ids
of all the currently-selected object points. The
second, called polygons[], contains the polygon
ids of all the currently-selected object polygons.

In the case of the automatic arrays points[] and polygons[], should you have declared arrays or variables with the same names within the scope of the MeshDataEdit mode, they will be hidden. They will become visible once again when you have terminated MeshDataEdit mode using editend().

editbegin() will return the count of points that are currently selected. This count will be equal to the size of the points[] automatic array.

     result                        // integer; count of
                                        // selected points
       editbegin(void)

editend (MD/1.0)

editend() is used to terminate MeshDataEdit mode (initiated with editbegin()). When called, the automatic arrays points[] and polygons[] will disappear, and CommandSequence (CS/1.0) functions and commands are once again available.

During MeshDataEdit operations, Modeler will "queue up" all modifications that are made to the object data. Modifications will not be applied to your object until you issue the editend() command. By default, if you provide no parameters to editend(), your changes will be applied to your object and processing will continue. However, you can provide a parameter to editend() that will cause your accumulated changes to be discarded, and leave your object unchanged. This parameter can be a constant, ABORT, or any non-zero value to indicate your wish to discard all changes.

     void editend([status])        // constant; ABORT

boundingbox (IN/1.0)

boundingbox() is used to return the upper and lower vectors that represent the bounding box of the object in specified layers. If no layers are specified, then the currently-selected foreground layer(s) are used by default.

boundingbox() can be called at anytime, regardless of mode. However, if boundingbox() is used during MeshDataEdit, layers cannot be specified, and any that are will be ignored.

If there are no point/polygon data in the specified layer(s), then nil will be returned for each vector.

     result                        // vector[2]; lower and
                                        // upper vectors of
                                        // bounding box or
                                        // nil[2] if no data
                                        // exists
       boundingbox([layers])       // integer or integer[]; an
                                        // integer array of
                                        // layer numbers, or
                                        // layer numbers
                                        // separated by commas

pointcount (IN/1.0)

pointcount() returns the number of currently-selected points in the active foreground layer(s). This value will be identical to that returned by the editbegin() function.

pointcount() can be called at any time.

     result                        // integer; selected-point
                                        // count
       pointcount(void)

polycount (IN/1.0)

The return value of polycount() is more complex than pointcount(), as it groups return values by the number of vertices a polygon contains. polycount() returns six (6) integer elements, representing:

[1] total number of selected polygons
[2] total number of selected polygons that contain
only one (1) point.
[3] total number of selected polygons that contain
only two (2) points
[4] total number of selected polygons that contain
only three (3) points
[5] total number of selected polygons that contain
only four (4) points
[6] total number of selected polygons that contain
more than four (4) points

This data can be used to examine the state of an object. For instance, before METAFORM'ing an object, you must convert all four-sided polygons into triangles. You could accomplish this with the following code snippet:

     var totalpoints[6];

     totalpoints = polycount();

     if(totalpoints[5] || totalpoints[6])
         triple();

     subdivide(METAFORM);
polycount() can be called at anytime, not necessarily only from within a MeshDataEdit mode.

     result                        // integer[6]; polygon
                                        // counts of varying
                                        // point counts
       polycount(void)

addpoint (MD/1.0)

addpoint() can be used to add new point data to your object. By providing a valid vector, addpoint() will return a valid point id that can be provided to other functions. If for some reason addpoint() fails to create a new point, nil will be returned.

     result                        // point id; the identifier
                                        // for the new vector
       addpoint(location)          // integer[3], vector or
                                        // number; the
                                        // location of the new
                                        // point

addpolygon (MD/1.0)

New polygons can be added to your object data using addpolygon(). One or more point ids can be provided to this function to generate the new polygon. If more than one point id is provided, they must be housed in an array.

The new polygon can optionally be assigned to a surface name. If the surface parameter is omitted, then the new polygon will belong to the default surface identifier. If the specified surface name does not exist, it will be created.

The new polygon identifier is returned upon success, or nil if there was a failure.

     result                        // polygon id or nil; the
                                        // identifier of the
                                        // new polygon
       addpolygon(points           // point id[] or point id;
                                        // point identifiers
                                        // of new polygon
                  [,surface])      // string; surface name to
                                        // which polygon
                                        // should be assigned

addcurve (MD/1.0)

addcurve() is identical to addpolygon() in both parameter types and counts. However, addcurve() will turn the provided point ids into a Modeler curve instead of a polygon. The difference between a polygon and a curve is that angles through curve points are smoothly interpolated, while angles through polygon points are strictly linear. To create a closed curve, the beginning and ending points provided must overlap.

The gears.ls sample script, provided on your distribution diskette, is a good example of using both addpolygon() and addcurve().

     result                        // polygon id or nil; the
                                        // identifier of the
                                        // new curve
       addcurve(points             // point id[] or point id;
                                        // point identifiers
                                        // of new curve
                  [,surface])      // string; surface name to
                                        // which curve
                                        // should be assigned

addquad (MD/1.0)

addquad() is used to add quadrangular (four-point) polygons to your object's mesh data. Point ids can be provided individually, or in an array of four (4) elements.

     result                        // polygon id; new polygon
                                        // identifier or nil
       addquad(points)             // point ids[4] or 4
                                        // individual point
                                        // ids; points to use
                                        // in constructing
                                        // quadrangle

addtriangle (MD/1.0)

addtriangle() is similar to addquad() in its parameter types, differing only in that it requires three (3) point ids to construct the new polygon instead of four (4).

     result                        // polygon id; new polygon
                                        // identifier or nil
       addtriangle(points)         // point ids[3] or 3
                                        // individual point
                                        // ids; points to use
                                        // in constructing
                                        // triangle

polyinfo (MD/1.0)

Information about individual polygons can be gathered using the polyinfo() function. polyinfo() returns a variable number of items whose first element is always the surface name to which the polygon is assigned. The remaining elements are comprised of the individual point ids of which the polygon is comprised.

Because not all polygons in an object will have the same number of points, the point count of a polygon will likely vary from polygon to polygon. To help you determine the number of points a polygon contains you can use the polypointcount() function (discussed next) to allocate an array of the appropriate size to hold the return value of polyinfo().

     result                        // array[]; variable
                                        // sized array whose
                                        // first element is
                                        // surface name,
                                        // remaining elements
                                        // are point ids
       polyinfo(polygon)           // polygon id; the polygon
                                        // identifier for
                                        // which you need
                                        // information

polypointcount (MD/1.0)

polypointcount() is used in conjunction with polyinfo() to determine the number of points a polygon contains. You will typically need this information when determining the size of an array to be used to hold the information returned by polyinfo(). For example,

     ...
     var pcount = polypointcount(polygons[x]);
     var ppoints[pcount + 1];  // account for surface name [1]
     ppoints = polyinfo(polygons[x]);
     ...
The prototype:

     result                        // integer; point count
       polypointcount(polygon)     // polygon id; the polygon
                                        // in question

pointinfo (MD/1.0)

pointinfo() returns the location in 3D space where a point resides.

     result                        // vector; location of
                                        // point
       pointinfo(point)            // point id; identifier of
                                        // point in which you
                                        // are interested

polynormal (MD/1.0)

polynormal() returns a vector representing the surface normal of the specified polygon.

     result                        // vector; surface normal
                                        // of polygon or nil
       polynormal(polygon)         // polygon id; identifier
                                        // of polygon

rempoint, rempoly (MD/1.0)

rempoint() and rempoly() will delete a point or polygon, respectively, from your objects mesh data. Note that in the case of rempoly(), the points comprising the polygon are not removed, and will remain as part of your mesh data.

     status rempoint(point)        // point id; the point to
                                        // be removed

     status rempoly(polygon)       // polygon id; the polygon
                                        // to be removed

pointmove (MD/1.0)

pointmove() will change the vector location of a point.

     status pointmove(point,       // point id; the point to
                                        // be moved
                      location)    // integer[3], vector or
                                        // number; the new
                                        // location of the
                                        // point

polysurface (MD/1.0)

polysurface() allows the LScript to reassign a polygon surface name.

     status polysurface(polygon,   // polygon id; the polygon
                                        // to change
                        surface)   // string; surface name to
                                        // which polygon is
                                        // now assigned

polypoints (MD/1.0)

polypoints() can be used to assign a new set of points to a polygon. The original points that comprised the polygon will not be automatically removed, and should be removed manually (using rempoint()) if no longer required.

     status polypoints(polygon,    // polygon id; polygon
                                        // to change
                       points      // point ids[]; new points
                                        // for polygon

Previous Section Table of Contents Index Errata
© 1996 Virtual Visions, Inc.
© 1997 NewTek, Inc.